// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 .
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : cpu_adapter.sv
// Author        : 
// Created On    : 2022-08-25 15:07
// Last Modified : 
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

`ifndef __CPU_ADAPTER_SV__
`define __CPU_ADAPTER_SV__

class cpu_adapter extends uvm_reg_adapter;

    `uvm_object_utils(cpu_adapter)
    
    extern function new(string name = "cpu_adapter");
    extern virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
    extern virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);

endclass: cpu_adapter

function cpu_adapter::new(string name = "cpu_adapter");
	super.new(name);
    provides_responses = 0;    
endfunction: new

function uvm_sequence_item cpu_adapter::reg2bus(const ref uvm_reg_bus_op rw);
    cpu_transaction cpu;
    cpu = cpu_transaction::type_id::create("cpu_trans");
    cpu.CPU_RW_TYPE = (rw.kind == UVM_READ) ? 1'b0 : 1'b1;
    cpu.CPU_ADDR = rw.addr;
    cpu.CPU_DATA = rw.data;
    //`uvm_warning("cpu_adapter", "call reg2bus over!")
    return cpu;
endfunction : reg2bus

function void cpu_adapter::bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
    cpu_transaction cpu;
    if(!$cast(cpu, bus_item)) begin
        `uvm_fatal("NO cpu TYPE","Provided bus_item is not of the correct type!")
        return;
    end
    //`uvm_warning("cpu_adapter", "call bus2reg!")
    rw.kind = (cpu.CPU_RW_TYPE == 1'b0) ? UVM_READ : UVM_WRITE;
    rw.addr = cpu.CPU_ADDR;
    rw.data = cpu.CPU_DATA;
    rw.status = UVM_IS_OK;
    //`uvm_warning("cpu_adapter", $sformatf("bus2reg get addr = 'h%0h, data='h%0h", rw.addr, rw.data));
endfunction : bus2reg

`endif
